package io.kiki.stack.netty.invoker;

import io.kiki.stack.netty.command.ResponseCommand;
import io.kiki.stack.netty.exception.InvokeTimeoutException;
import io.kiki.stack.netty.exception.RemotingException;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Setter
@Getter
public class RpcResponseFuture {
    /**
     * rpc server address
     */
    private final String addr;

    /**
     * rpc server port
     */
    private final Future future;


    public RpcResponseFuture(String addr, Future future) {
        this.addr = addr;
        this.future = future;
    }

    /**
     * Whether the future is done.
     */
    public boolean isDone() {
        return this.future.isDone();
    }

    /**
     * get result with timeout specified
     * <p>
     * if request done, resolve normal responseObject
     * if request not done, throws InvokeTimeoutException
     */
    public Object get(int timeoutMillis) throws RemotingException, InterruptedException {
        this.future.waitResponse(timeoutMillis);
        if (!isDone()) {
            throw new InvokeTimeoutException("Future get result timeout!");
        }
        ResponseCommand responseCommand = (ResponseCommand) this.future.waitResponse();
        responseCommand.setRequestContext(this.future.getInvokeContext());
        return RpcResponseResolver.resolveResponseObject(responseCommand, addr);
    }

    public Object get() throws RemotingException, InterruptedException {
        ResponseCommand responseCommand = (ResponseCommand) this.future.waitResponse();
        responseCommand.setRequestContext(this.future.getInvokeContext());
        return RpcResponseResolver.resolveResponseObject(responseCommand, addr);
    }

}
